package com.example.petcare.service.serviceImpl;


import com.example.petcare.exception.NoValueException;
import com.example.petcare.exception.OrderException;
import com.example.petcare.mapper.HostMapper;
import com.example.petcare.mapper.UserMapper;
import com.example.petcare.pojo.*;
import com.example.petcare.service.HostService;
import com.example.petcare.utils.ThreadLocalUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
public class HostServiceImpl implements HostService {

    @Autowired
    private HostMapper hostMapper;

    // 注入userMapper
    @Autowired
    private UserMapper userMapper;

    // 发布托管需求
    @Override
    public void add(HostDemand hostDemand) {


        // 给订单的userId赋值
        Map<String,Object> map = ThreadLocalUtil.get();// 从ThreadLocal中获取用户信息
        Integer id = (Integer) map.get("userId");// 从map中获取用户id


        // 判断用户是否审核通过，如果没有审核通过，不能发布托管需求
        User user = userMapper.findById(id);

        if (user.getAuditStatus() == 0) {
            throw new NoValueException("用户未审核通过，不能发布托管需求");
        }


        // 先判断宠物id, 托管天数, 托管开始时间, 地点，价格，是否为null
        if (hostDemand.getPetId() == null ||
                hostDemand.getPetId().toString().trim().isEmpty() ||  // 确保 petId 不为空或只包含空格
                hostDemand.getDays() == null ||
                hostDemand.getDays().toString().trim().isEmpty() ||  // 确保 days 不为空或只包含空格
                hostDemand.getStartDate() == null ||
                hostDemand.getStartDate().toString().trim().isEmpty() ||  // 确保 startDate 不为空或只包含空格
                hostDemand.getLocation() == null ||
                hostDemand.getLocation().trim().isEmpty() ||  // 确保 location 不为空或只包含空格
                hostDemand.getPrice() == null ||
                hostDemand.getPrice().toString().trim().isEmpty()) {  // 确保 price 不为空或只包含空格
            throw new NoValueException("宠物ID、托管天数、开始时间、地点和价格不能为空");
        }



        // 委托时长不能小于1天
        if (hostDemand.getDays() < 1) {
            throw new NoValueException("委托时长不能小于1天");
        }




        hostDemand.setUserId(id);

        // 给订单的status,orderStatus,rejectStatus,payStatus赋值
        hostDemand.setStatus(false);
        hostDemand.setOrderStatus(false);
        hostDemand.setRejectStatus(false);
        hostDemand.setPayStatus(false);




        // 给时间补8小时
        hostDemand.setStartDate(hostDemand.getStartDate().plusHours(8));


        // 判断时间是否小于中国当地时间
        if (hostDemand.getStartDate().isBefore(hostDemand.getStartDate().now())) {
            throw new NoValueException("开始时间不能小于当前时间");
        }

        hostMapper.add(hostDemand);
    }

    // 查询托管需求列表（条件分页查询）
    @Override
    public PageBean<HostDemand> list(Integer pageNum, Integer pageSize, Integer petId, String location, Integer status) {

        // 1.创建PageBean对象
        PageBean<HostDemand> pb = new PageBean<>();

        // 2.开启分页查询     PageHelper
        PageHelper.startPage(pageNum,pageSize);// 返回的是Page对象

        // 3.调用mapper
        Map<String,Object> map = ThreadLocalUtil.get();
        Integer userId = (Integer) map.get("userId");

        List<HostDemand> list = hostMapper.list(userId,petId,location,status);

        // Page中提供了方法，可以获取PageHelper分页查询后 得到的总记录条数和当前页数据
        // 不强转，多肽它是不允许使用父类类型去调用子类特有的方法的，所以需要强转
        Page<HostDemand> p =(Page<HostDemand>) list;// Page是一个List的子类，实现类

        // 把数据填充到PageBean对象中
        pb.setTotal(p.getTotal());
        pb.setItems(p.getResult());

        return pb;
    }

    // 修改托管需求
    @Override
    public void update(HostDemand hostDemand) {

        // 判断宠物id, 托管天数, 托管开始时间, 地点，价格，是否为null
        if (hostDemand.getPetId() == null ||
                hostDemand.getPetId().toString().trim().isEmpty() ||  // 确保 petId 不为空或只包含空格
                hostDemand.getDays() == null ||
                hostDemand.getDays().toString().trim().isEmpty() ||  // 确保 days 不为空或只包含空格
                hostDemand.getStartDate() == null ||
                hostDemand.getStartDate().toString().trim().isEmpty() ||  // 确保 startDate 不为空或只包含空格
                hostDemand.getLocation() == null ||
                hostDemand.getLocation().trim().isEmpty() ||  // 确保 location 不为空或只包含空格
                hostDemand.getPrice() == null ||
                hostDemand.getPrice().toString().trim().isEmpty()) {  // 确保 price 不为空或只包含空格
            throw new NoValueException("宠物ID、托管天数、开始时间、地点和价格等不能为空");
        }

        // 如果商家已接单，不能修改，商家已经完成订单，不能修改
        HostDemand hd = hostMapper.findById(hostDemand.getHostId());
        // 如果单纯是已经接单，不能修改，弹出的是商家已接单，不能修改
        if (hd.isStatus()) {
            throw new OrderException("商家已接单，不能修改");
        }

        // 如果是已经完成订单且商家是拒单状态，不能修改，弹出的是商家拒单，不能修改
        if (hd.isRejectStatus()) {
            throw new OrderException("商家拒单，不能修改");
        }


        // 如果是已经完成订单且商家是接单状态，不能修改，弹出的是商家已接单，不能修改
        if (hd.isOrderStatus()) {
            throw new OrderException("订单已完成，不能修改");
        }




        // 给时间补8小时
        hostDemand.setStartDate(hostDemand.getStartDate().plusHours(8));


        // 判断时间是否小于中国当地时间
        if (hostDemand.getStartDate().isBefore(hostDemand.getStartDate().now())) {
            throw new NoValueException("开始时间不能小于当前时间");
        }


        hostMapper.update(hostDemand);

    }

    // 删除托管需求
    @Override
    public void delete(Integer hostId) {

        // 先判断商家是否接单，如果接单了，不能删除，即订单状态(status)为true,但是接单并且完成订单的情况下，可以删除
        HostDemand hostDemand = hostMapper.findById(hostId);
        if (hostDemand.isStatus()) {
            if(!hostDemand.isOrderStatus()){
                throw new OrderException("商家已接单，不能删除");
            }
        }

        hostMapper.delete(hostId);

    }

    // 查询所有已经审核过的商家的具体信息，从provider表中查询
    @Override
    public List<Provider> listProvider() {
        return hostMapper.listProvider();
    }


    // 删除已经被拒单的托管需求，利用userId删除，userId从threadLocal中获取
    @Override
    public void deleteByUserId() {

        Map<String,Object> map = ThreadLocalUtil.get();
        Integer userId = (Integer) map.get("userId");
        hostMapper.deleteByUserId(userId);


    }

    // 查询当前用户被拒单的托管需求
    @Override
    public List<HostDemand> listReject() {

        Map<String,Object> map = ThreadLocalUtil.get();
        Integer userId = (Integer) map.get("userId");
        return hostMapper.listReject(userId);

    }

    //  是否有新订单
    @Override
    public Integer hasAccept() {

        Map<String,Object> map = ThreadLocalUtil.get();
        Integer userId = (Integer) map.get("userId");
        return hostMapper.hasAccept(userId);

    }

    // 是否有订单完成
    @Override
    public Integer hasFinish() {

        Map<String,Object> map = ThreadLocalUtil.get();
        Integer userId = (Integer) map.get("userId");
        return hostMapper.hasFinish(userId);


    }

    // 查询托管需求详情
    @Override
    public HostDemand findById(Integer hostId) {

        return hostMapper.findById(hostId);


    }

    // 更新支付状态
    @Override
    public void updatePayStatus(Integer hostId) {

        hostMapper.updatePayStatus(hostId);

    }

    // 查看增值商品列表
    @Override
    public List<Goods> getGoodsList(Integer hostId) {

        // 先根据hostId查询托管需求
        HostDemand hostDemand = hostMapper.findById(hostId);

        // 然后获取到providerId
        Integer providerId = hostDemand.getProviderId();

        // 根据providerId查询增值商品
        List<Goods> goodsList = hostMapper.getGoodsList(providerId);

        return goodsList;


    }

    // 根据providerId查询商家信息
    @Override
    public Provider getProviderById(Integer hostId) {

        // 先根据hostId查询托管需求
        HostDemand hostDemand = hostMapper.findById(hostId);


        // 然后获取到providerId
        Integer providerId = hostDemand.getProviderId();

        // 如果providerId为null，抛出异常
        if (providerId == null) {
            throw new NoValueException("商家未接单，不能查询商家信息");
        }


        // 根据providerId查询商家信息
        Provider provider = hostMapper.getProviderById(providerId);

        // 如果没有数据，抛出异常
        if (provider == null) {
            throw new NoValueException("没有该商家信息");
        }

        return provider;
    }


}
